#ifndef __core_style_h__
#define __core_style_h__

#include "core/attribute.hpp"
#include "base/def.h"
#include "core/const.h"


namespace core
{
    /*
     * @brief : style object
     */
    class StStyle : public StAttributeSet
    {
    public:
        DECLARE_ATTRIBUTE_MAP();

        enum StyleType
        {
            STYLE_TAG,
            STYLE_CLASS,
            STYLE_IDENTIFIER
        };

        StStyle();
        StStyle(const StStyle&);
        ~StStyle();
        StStyle& operator=(const StStyle&);


        const char * ParseValue (const char * p);
        void         ParseValues(const char * p);
        const char * ParseStyle (const char * p);

        StyleType Type() const                         { return type_; }
        void SetType(StyleType type)                   { type_ = type; }

        const std::string & Name() const               { return name_; }
        void SetName(const std::string &s)             { name_ = s; }

        const ActionState State() const                { return state_; }
        void SetState(ActionState state)               { state_ = state; }

        void Copy(const StStyle& style);
        void Inherit(const StStyle& style);

    private:
        bool ParseBackground(const char *p);
        bool ParseMargin(const char *p);
        bool ParsePadding(const char *p);
        bool ParseFont(const char *p);
        bool ParseBorder(const char *p);

    private:
        StyleType   type_;
        ActionState state_;
        std::string name_;
    };

    /*
     * @brief : style cache object
     */
    class StStyleCache
    {
    public:
        StStyleCache() {}
        ~StStyleCache() {}

        bool Parse(const char *p);

        bool GetStyleByClass(const std::string& classname,
            core::StStyle* style, ActionState state = ACTION_STATE_NORMAL) const;

        bool GetStyleById(const std::string& id,
            core::StStyle* style, ActionState state = ACTION_STATE_NORMAL) const;

        bool GetStyleByName(const std::string& name,
            core::StStyle* style, ActionState state = ACTION_STATE_NORMAL) const;

    private:
        struct StyleHolder
        {
            StStyle style_normal_;
            StStyle style_hover_;
            StStyle style_down_;
        };
        typedef std::map<std::string, StyleHolder> CacheMap;

    private:
        bool Get(const std::string &name,
            const CacheMap &cache, StStyle* style, ActionState state) const;
        bool Set(const std::string &name,
            CacheMap &cache, StStyle &style, ActionState state);

    private:
        CacheMap cache_class_;
        CacheMap cache_identifier_;
        CacheMap cache_tag_;

    private:
        DISABLE_COPY_AND_ASSIGN(StStyleCache)
    };
}

#endif